#!/usr/bin/env python
# -*- mode: python; coding: utf-8; -*-
##--------------------------------------------------------------------------##
##
## Copyright (C) 1998-2003 Markus Oberhumer <markus@oberhumer.com>
## Copyright (C) 2003 Mt. Hood Playing Card Co.
## Copyright (C) 2005-2010 Skomoroh <skomoroh@users.sourceforge.net>
## Copyright (C) 2010-2013 Jeremy Austin-Bardo <tjaustinbardo@gmail.com>
##
## This program is free software: you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation, either version 3 of the License.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program.  If not, see <http://www.gnu.org/licenses/>.
##
##--------------------------------------------------------------------------##
"""
Yukon style stacks
"""

from .. import pilelib as stack
from .. import hint
from .. import helpstrings as hs


class Hint(hint.CautiousDefaultHint):
    BONUS_FLIP_CARD = 9000
    BONUS_CREATE_EMPTY_ROW = 100

    def pile_sequences(self, stack):
        """
        pile_sequences(stack:Stack)) -> seq(seq(Card ...) ...)

        Returns piles that play from **stack**.

        Augment asking **stack** for its **SEQUENCE** then split possible piles.
        """
        piles = super(Hint, self).pile_sequences(stack)[0]
        return tuple(piles[i:] for i in range(len(piles)))

    def score_move_pile(self, from_stack, to_stack, pile, rpile):
        """
        score_move_pile(from_stack:Stack, to_stack:Stack, pile:seq(Card ...),
          rpile:seq(Card ...)) -> None

        Score moving a pile from stack to to stack.

        Augment **from_stack** builds **to_stack** prefer move does not block,
        (i.e. Card in pile, but needed for another stack).

        FIXME: Rough approximation, but doesn't seem to help Russian Solitaire
        """
        score = self._score
        super(Hint, self).score_move_pile(from_stack, to_stack, pile, rpile)
        score = self._score - bonus
        to_pile = to_stack.SEQUENCE
        if to_pile:
            for from_card in pile:
                fc_stack = hint.AClonedStack.clone(from_stack,
                                                   cards=[from_card])
                for to_card in to_pile:
                    if fc_stack.cardsBuild(to_stack, [to_card]):
                        score = ((score / 1000) * 1000) + score % 100
                        break
        self._score += score


class StackMethods(object):
    """
    Supports movement of any open cards.
    """

    def _build_sequence(self, cards):
        """
        _build_sequence(cards:tup) -> bool

        :param tuple cards: cards to accept from another pile
        :return: base card acceptable?
        :rtype: boolean
        """
        return self._sequence(cards[:1])


    def _play_sequence(self, cards):
        """
        _play_sequence(cards:obj) -> bool

        Any cards may move.

        :param sequence cards: cards from this pile
        :return: cards moveable?
        :rtype: boolean
        """
        return True

    @property
    def _helpString(self):
        """
        _helpString -> str

        :return: helpful string about pile for its canvas label.
        :rtype:  base_string
        """
        build = super(StackMethods, self)._helpString
        return "{0} {1}".format(build, hs.YUKON_STR).strip()


class AC_RowStack(StackMethods, stack.AC_RowStack):
    """
    Build down in rank by alt color. Play any.
    """
    pass


class SS_RowStack(StackMethods, stack.SS_RowStack):
    """
    Build down in rank by same suit. Play any.
    """
    pass


class RK_RowStack(StackMethods, stack.RK_RowStack):
    """
    Build down in rank alone. Play any.
    """
    pass


class BO_RowStack(StackMethods, stack.BO_RowStack):
    """
    Build down in rank by alt suit. Play any.
    """
    pass


class UD_SS_RowStack(StackMethods, stack.UD_SS_RowStack):
    """
    Build either in rank by same suit. Play any.
    """
    pass


class UD_AC_RowStack(StackMethods, stack.UD_AC_RowStack):
    """
    Build either in rank by alt color. Play any.
    """
    pass